オンプレミスのマシンにCloud9のSSH環境を構築して接続してみた
こんにちは、なおにしです。
手元にあったマシン(Ubuntu Server)に AWS Cloud9から接続できるようにしてみましたのでご紹介します。
はじめに
AWS Cloud9 を開始する際には、EC2環境とSSH環境の2種類が選べるようになっています。
バックグラウンドで、環境をコンピューティングリソースに接続する方法がいくつかあります。
- Amazon EC2 インスタンスを作成し、 環境を新しく作成した EC2 インスタンスに接続するよう、AWS Cloud9 に指示できます。このタイプのセットアップを EC2 環境と呼びます。
- 環境を既存のクラウドコンピューティングインスタンスや独自のサーバーに接続するよう AWS Cloud9 に指示することもできます。このタイプのセットアップを SSH 環境と呼びます。
SSH環境では、既存のEC2インスタンスに対して接続することもできますが、インターネット経由でオンプレミスやその他のIaaS上のサーバに接続することも可能となっています。
つまり、既存のEC2にCloud9をセットアップして接続するパターンは「EC2環境」ではなく「SSH環境」になりますので、ご注意ください。
ユースケース
Cloud9 のEC2環境とSSH環境の違いは以下にまとまっています。
ざっくりまとめるとSSH環境を使用する方が環境準備に手間がかかりますし、一部機能が使えなかったりします。さらに、ドキュメントでも複数箇所に記載がありますが、AWSとしてもEC2環境の使用を勧めています。
しかし、例えば以下のようなメリットもあります。
- EC2インスタンスが稼働することに伴う維持費を抑えたい
- オンプレの維持費の方がかかるのでは?と思われるかもしれませんが、例えば既にレンタルサーバを契約しているパターンなどでは有効です
- Webブラウザを用いてオンプレミス環境のサーバでファイル編集・開発がしたい、または踏み台にもしたい
- System Managerでもできのでは?と思われるかもしれませんが、Cloud9というリッチなエディタ機能付きで接続できます
- EC2インスタンスの起動・停止を意識する必要がなくなる
- これは大きいかもしれません
というわけで、今回はローカル環境のUbuntu Server(22.04 LTS)に必要なパッケージをインストールして、SSH環境でのCloud9をセットアップしてみます。
やってみた
構成は以下のとおりです。
Cloud9からの接続先となるオンプレミス環境(自宅)には固定IPがありませんでした。このような環境で構築する場合はダイナミックDNS(DDNS)サービスを使用することをお勧めします。市販のルーターでもDDNSを利用できる製品もあると思いますので(有償かもしれませんが)ご確認ください。
Ubuntu Server側の設定
以下の要件を満たすようにマシンにログインして各種パッケージをインストールします。
まず、事前に必要なパッケージをインストールします。
$ sudo apt update $ sudo apt install build-essential
Cloud9用のユーザを追加する場合は、以下をご参照ください。今回は新規に「cloud9user」というユーザを追加しました。
$ sudo adduser cloud9user [sudo] ubuntu のパスワード: ユーザー `cloud9user' を追加しています... 新しいグループ `cloud9user' (1004) を追加しています... 新しいユーザー `cloud9user' (1001) をグループ `cloud9user' に追加しています... ホームディレクトリ `/home/cloud9user' を作成しています... `/etc/skel' からファイルをコピーしています... 新しい パスワード: 新しい パスワードを再入力してください: passwd: パスワードは正しく更新されました cloud9user のユーザ情報を変更中 新しい値を入力してください。標準設定値を使うならリターンを押してください フルネーム []: 部屋番号 []: 職場電話番号 []: 自宅電話番号 []: その他 []: 以上で正しいですか? [Y/n] Y $ sudo usermod -aG adm,sudo cloud9user $ id cloud9user uid=1001(cloud9user) gid=1004(cloud9user) groups=1004(cloud9user),4(adm),27(sudo) $ su - cloud9user パスワード: To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. $ pwd /home/cloud9user
ドキュメントには以下の記載があります。
既存のインスタンスやサーバーでログイン後に AWS Cloud9 の起動元とするディレクトリパスには、
rwxr-xr-x
に設定されたアクセス許可が必要です。
したがって、上記のとおりcloud9userを追加した場合は、cloud9userでログインしている状態で以下のコマンドを実行します。
$ sudo chmod u=rwx,g=rx,o=rx ~
続いて、Node.jsをインストールするために先にNode Version Manager (nvm) をインストールします。
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
パスが通った状態にするために一度ログアウトして再度ログインします。nvmが実行できることを確認します。
$ nvm --version 0.39.5
最新のNode.jsをインストールする場合は以下のコマンドを実行します。
$ nvm install --lts && nvm alias default lts/*
インストールが完了したら、Node.jsのバージョンを確認します。
$ node --version v20.15.0
続いて、Cloud9 インストーラーをダウンロードして実行します。
$ curl -L https://d3kgj69l4ph6w4.cloudfront.net/static/c9-install-2.0.0.sh | bash
私の環境では以下のように出力されたので、記載のとおりpython3-venvをインストールしてから再度上記を実行します。
venv and ensurepip is required to create virtual environment. Please run command 'sudo apt install python3-venv' to install dependencies.
gccでコンパイルしたり各種パッケージをダウンロードしてきたりしているようで、インストールにはかなり時間がかかりました。私の環境では20分ほどかかりました。
ネットワーク設定
Cloud9から対象のマシンにアクセスするにはインターネットからのSSH接続が可能となるように設定する必要があります。
とはいえ、どこからでもアクセスできる状態にしたままだと不安なので、ルーターが対応しているのであればCloud9が使用するIPアドレス範囲のみを接続元として許可するように設定することを推奨します。
Cloud9からの送信元IPアドレス範囲の確認方法は以下に記載があります。
東京リージョンでの送信元IPアドレスを確認してみます。
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq '.prefixes[] | select(.service=="CLOUD9" and .region=="ap-northeast-1")'
以下のとおり出力されました。
{ "ip_prefix": "18.179.48.128/27", "region": "ap-northeast-1", "service": "CLOUD9", "network_border_group": "ap-northeast-1" } { "ip_prefix": "18.179.48.96/27", "region": "ap-northeast-1", "service": "CLOUD9", "network_border_group": "ap-northeast-1" }
2つのセグメントのみですので、送信元IPアドレスとしてフィルタリング登録することも大変ではありません(もちろん将来的に増える可能性もありますのでご注意ください)。 もしルーターにFW機能が存在しない場合でも、接続先マシンのOSのFW機能(今回のようにUbuntuであればufw)を利用してフィルタリングすることもできます。その際はルーターがNATしないように設定をご確認ください。
Cloud9(AWSマネジメントコンソール)側の設定
それではAWSマネジメントコンソールからCloud9を用いて対象のマシンに接続できるように設定します。
Cloud9の設定画面から[環境を作成]を選択し、[既存のコンピューティング]を選択します。
Ubuntuで作成したユーザとDDNSのFQDN、ルーター側でマップしたポート番号をそれぞれ入力します。
上記の画面に記載のとおりSSH接続の際は公開鍵認証を使用するため、Cloud9userのホームディレクトリ配下の[ ~/.ssh/authorized_keys]ファイルに公開鍵情報を追記します。
$ vi ~/.ssh/authorized_keys
authorized_keysファイルが存在せず、新規で作成した場合はパーミッション設定を忘れないようにしてください。
$ chmod 600 ~/.ssh/authorized_keys
上記までが完了したので[作成]ボタンを押下すると、エラーが出力されました。
「Could not execute node.js on example.com(DDNSドメイン名)」とあるので、Node.jsのパスの問題かと思い確認しましたが、前述の手順でバージョン表示ができていたので当然通っています。念のため、「nodejs-legacy」パッケージをインストールする代わりにnodejs用のシンボリックリンクを作成してみましたが改善しませんでした。
そこで、以下のように[その他の詳細 - オプション]内に[Node.jsバイナリへのパス]という項目があったので入力してみたところ、作成することができました。
上記の項目はドキュメントには以下のように説明があります。今回はこちらの手順に基づいてNode.jsをインストールしましたが、Node.jsバイナリの場所の推測先には含まれていないようです。aptなどのパッケージマネージャーを使用して/usr/bin/配下にインストールされた場合は設定不要かもしれません。
(Node.js バイナリへのパス) にパス情報を入力し、インスタンスまたはサーバーの Node.js バイナリへのパスを指定します。パスを取得するには、インスタンスまたはサーバーでコマンド
which node
(nvm
を使用している場合はnvm which node
) を実行できます。例えば、パスは/usr/bin/node
のようになります。空白のままにした場合、 AWS Cloud9 は接続の試行時に Node.js バイナリの場所の推測を試みます。
環境が作成されたら以下のようにCloud9の環境が表示されるので、Cloud9 IDEを開いてみます。
IDEが開きました。画面下部のTerminalでも今回作成したcloud9userでログインできています。
まとめ
実は今回検証に使った手元のマシンはRaspberry Pi 4 です。このためCPUアーキテクチャはArmでした。。 検証を始めた後に気づいたのですが、ドキュメントには以下のとおりきちんと明記されています。
Arm ベースのアーキテクチャを使用することはできません。(Arm プロセッサを中心に構築されたシステムのサポートは検討中です)。
ですがx86のサーバは手元になかったのでとりあえずできるところまでやってみた結果、IDE起動までは無事に確認できたという状態です。
IDEは起動できているもののこちらの記事のように不具合が発生する可能性もあり、そもそもサポート対象外なので、本記事と同様にSSH環境を構築される場合はCPUアーキテクチャにご注意ください。
本記事がどなたかのお役に立てれば幸いです。